package com.mall.mymall.common;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.HexFormat;
import java.util.Map;

@RestController
@RequestMapping("/file")
public class FileController {
    @Value("${fileAddr}")
    private String fileAddr;

    @PostMapping("/upload")
    public Result<Map<String, String>> uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam("entityId") Long entityId,
            @RequestParam("entityType") String entityType) {
        // 根据entityType和entityId生成文件路径
        String fileUrl = saveFile(file, entityId, entityType);
        return Result.success((Collections.singletonMap("fileUrl", fileUrl)));
    }

    private String saveFile(MultipartFile file, Long entityId, String entityType) {
        try {
            // 定义文件保存目录，根据entityType动态生成
            String uploadDir = "src/main/resources/files/" + entityType + "/";
            File directory = new File(uploadDir);
            if (!directory.exists()) {
                directory.mkdirs();  // 如果目录不存在，则创建目录
            }

            // 计算文件内容的MD5值
            String md5Hash = calculateMD5(file.getInputStream());

            // 生成文件名：entityType + "_" + entityId + "_" + MD5值 + 原文件扩展名
            String fileName = entityType + "_" + entityId + "_" + md5Hash + getFileExtension(file.getOriginalFilename());
            Path filePath = Paths.get(uploadDir, fileName);

            // 检查文件是否已存在
            if (Files.exists(filePath)) {
                return fileAddr + entityType + "/" + fileName; // 如果文件已存在，直接返回文件URL
            }

            // 保存文件
            Files.copy(file.getInputStream(), filePath);

            // 返回文件的访问URL（假设文件可通过URL访问）
            return fileAddr + entityType + "/" + fileName;
        } catch (IOException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "文件上传失败";  // 出现异常时返回错误信息
        }
    }

    // 辅助方法：计算MD5值
    private String calculateMD5(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");  // 获取MD5算法实例
        byte[] buffer = new byte[8192];  // 缓冲区大小
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {  // 逐块读取文件内容
            md.update(buffer, 0, bytesRead);  // 更新MD5摘要
        }
        byte[] digest = md.digest();  // 完成摘要计算
        return HexFormat.of().formatHex(digest);  // 将摘要转换为16进制字符串
    }

    // 辅助方法：提取文件扩展名
    private String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');  // 查找文件名中的最后一个点（.）
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {  // 确保文件名中有扩展名
            return fileName.substring(dotIndex);  // 返回扩展名
        }
        return "";  // 如果没有扩展名，返回空字符串
    }

}
